//
//  DoubleShadowView.swift
//  BasicProduct
//
//  Created by iOS on 2022/6/1.
//

import UIKit

/// 向外双阴影
open class ZLEctadDoubleShadowView: UIView {
    
    public var borderStyle: ZLBorderStyle = .inside {
        didSet {
            layoutSubviews()
        }
    }
    
    open override var backgroundColor: UIColor? {
        didSet {
            lightLayer.backgroundColor = backgroundColor?.cgColor
            darkLayer.backgroundColor = backgroundColor?.cgColor
        }
    }
    
    public var cornerRadius: CGFloat = 0 {
        didSet {
            layer.cornerRadius = cornerRadius
            lightLayer.cornerRadius = cornerRadius
            darkLayer.cornerRadius = cornerRadius
            if border {
                borderLayer.cornerRadius = cornerRadius
            }
        }
    }
    
    public var lightOpacity: Float = 1.0 {
        didSet {
            lightLayer.shadowOpacity = lightOpacity
        }
    }
    
    public var lightColor: UIColor = .hex_FFFFFF {
        didSet {
            lightLayer.shadowColor = lightColor.cgColor
        }
    }
    
    public var lightOffset: CGPoint = .zero {
        didSet {
            lightLayer.shadowOffset = .init(width: lightOffset.x, height: lightOffset.y)
        }
    }
    
    public var lightDiameter: CGFloat = 20 {
        didSet {
            lightLayer.shadowRadius = lightDiameter / 2
        }
    }
    
    public var darkOpacity: Float = 1.0 {
        didSet {
            darkLayer.shadowOpacity = darkOpacity
        }
    }
    
    public var darkColor: UIColor = .hex_364883 {
        didSet {
            darkLayer.shadowColor = darkColor.cgColor
        }
    }
    
    public var darkOffset: CGPoint = .zero {
        didSet {
            darkLayer.shadowOffset = .init(width: darkOffset.x, height: darkOffset.y)
        }
    }
    
    public var darkDiameter: CGFloat = 20 {
        didSet {
            darkLayer.shadowRadius = darkDiameter / 2
        }
    }
    
    lazy public var lightLayer: CALayer = {
        let layer = CALayer()
        return layer
    }()
    
    lazy public var darkLayer: CALayer = {
        let view = CALayer()
        return view
    }()
    
    lazy public var borderLayer: BorderLayer = {
        let view = BorderLayer()
        view.defaultConfig()
        return view
    }()
        
    public var border: Bool = false {
        didSet {
            layoutSubviews()
        }
    }
    
    public init(border: Bool = false) {
        super.init(frame: .zero)
        self.border = border
        clipsToBounds = false
        addSubviews()
    }
    
    required public init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    open override func layoutSubviews() {
        super.layoutSubviews()
        CATransaction.begin()
        CATransaction.setDisableActions(true)
        lightLayer.frame = bounds
        darkLayer.frame = bounds
        if border {
            var borderX: CGFloat = 0
            var borderY: CGFloat = 0
            var borderWidth: CGFloat = bounds.width
            var borderHeight: CGFloat = bounds.height
            if borderStyle == .center {
                borderX = -borderLayer.maskLayer.borderWidth / 2
                borderY = -borderLayer.maskLayer.borderWidth / 2
                borderWidth = bounds.width + borderLayer.maskLayer.borderWidth
                borderHeight = bounds.height + borderLayer.maskLayer.borderWidth
            }else if borderStyle == .outside {
                borderX = -borderLayer.maskLayer.borderWidth
                borderY = -borderLayer.maskLayer.borderWidth
                borderWidth = bounds.width + borderLayer.maskLayer.borderWidth * 2
                borderHeight = bounds.height + borderLayer.maskLayer.borderWidth * 2
            }
            borderLayer.frame = .init(x: borderX, y: borderY, width: borderWidth, height: borderHeight)
        }
        CATransaction.commit()
    }
    
    private func addSubviews() {
        layer.addSublayer(darkLayer)
        layer.addSublayer(lightLayer)
        if border {
            layer.addSublayer(borderLayer)
        }
    }
    
}

// 事件区
extension ZLEctadDoubleShadowView {
    
    /// 默认配置
    ///
    ///```
    ///backgroundColor = .hex_EBEBEB
    ///cornerRadius = 10
    ///lightOpacity = 1.0
    ///lightColor = .hex_FFFFFF
    ///lightOffset = .init(x: -2, y: -2)
    ///lightDiameter = 3
    ///darkOpacity = 0.4
    ///darkColor = .hex_555555
    ///darkOffset = .init(x: 2, y: 2)
    ///darkDiameter = 4
    ///```
    ///
    public func defaultConfig() {
        borderStyle = .inside
        backgroundColor = .hex_EBEBEB
        cornerRadius = 10
        lightOpacity = 1.0
        lightColor = .hex_FFFFFF
        lightOffset = .init(x: -2, y: -2)
        lightDiameter = 3
        darkOpacity = 0.4
        darkColor = .hex_555555
        darkOffset = .init(x: 2, y: 2)
        darkDiameter = 4
    }
    
}

// 定制区
public extension ZLEctadDoubleShadowView {
    
    class BorderLayer: CALayer {
        
        public enum GradientPoint {
            case leftTop
            case leftBottom
            case rightTop
            case rightBottom
        }
        
        public override var cornerRadius: CGFloat {
            didSet {
                gradualLayer.cornerRadius = cornerRadius
                maskLayer.cornerRadius = cornerRadius
                layoutSublayers()
            }
        }
        
        public var colors: [UIColor] = [] {
            didSet {
                var colors_cg: [CGColor] = []
                for color in colors {
                    colors_cg.append(color.cgColor)
                }
                gradualLayer.colors = colors_cg
            }
        }
        
        /* An optional array of Float objects defining the location of each
         * gradient stop as a value in the range [0,1]. The values must be
         * monotonically increasing. If a nil array is given, the stops are
         * assumed to spread uniformly across the [0,1] range. When rendered,
         * the colors are mapped to the output colorspace before being
         * interpolated. Defaults to nil. Animatable. */
        
        public var locations: [Float]? {
            didSet {
                var locations_ns: [NSNumber] = []
                for value in locations ?? [] {
                    locations_ns.append(NSNumber(value: value))
                }
                gradualLayer.locations = locations_ns.count > 0 ? locations_ns : nil
            }
        }
        
        public var startPoint: GradientPoint = .leftTop {
            didSet {
                switch startPoint {
                    case .leftTop:
                        gradualLayer.startPoint = CGPoint(x: 0, y: 0)
                    case .leftBottom:
                        gradualLayer.startPoint = CGPoint(x: 0, y: 1)
                    case .rightTop:
                        gradualLayer.startPoint = CGPoint(x: 1, y: 0)
                    case .rightBottom:
                        gradualLayer.startPoint = CGPoint(x: 1, y: 1)
                }
            }
        }

        public var endPoint: GradientPoint = .leftTop {
            didSet {
                switch endPoint {
                    case .leftTop:
                        gradualLayer.endPoint = CGPoint(x: 0, y: 0)
                    case .leftBottom:
                        gradualLayer.endPoint = CGPoint(x: 0, y: 1)
                    case .rightTop:
                        gradualLayer.endPoint = CGPoint(x: 1, y: 0)
                    case .rightBottom:
                        gradualLayer.endPoint = CGPoint(x: 1, y: 1)
                }
            }
        }
        
        lazy public var gradualLayer: CAGradientLayer = {
            let layer = CAGradientLayer()
            layer.mask = maskLayer
            return layer
        }()
        
        lazy public var maskLayer: CAShapeLayer = {
            let layer = CAShapeLayer()
            layer.fillColor = UIColor.clear.cgColor
            layer.strokeColor = UIColor.white.cgColor
            return layer
        }()
        
        override public init(layer: Any) {
            super.init(layer: layer)
        }
        
        override public init() {
            super.init()
            addSublayers()
        }
        
        required public init?(coder: NSCoder) {
            fatalError("init(coder:) has not been implemented")
        }
        
        public override func layoutSublayers() {
            super.layoutSublayers()
            CATransaction.begin()
            CATransaction.setDisableActions(true)
            gradualLayer.frame = bounds
            maskLayer.frame = bounds
            maskLayer.path = UIBezierPath(roundedRect: bounds, cornerRadius: cornerRadius).cgPath
            CATransaction.commit()
        }
        
        private func addSublayers() {
            addSublayer(gradualLayer)
        }
        
        /// 默认配置
        ///
        ///```
        ///maskLayer.borderWidth  = 1.0
        ///colors                 = [.hex_FFFFFF, .hex_ACB5DB]
        ///startPoint             = .leftTop
        ///endPoint               = .rightBottom
        ///```
        ///
        public func defaultConfig() {
            maskLayer.borderWidth = 1.0
            colors = [.hex_FFFFFF.withAlphaComponent(0.347), .hex_A8A8A8]
            startPoint = .leftTop
            endPoint = .rightBottom
        }
        
    }
    
}
